package com.lyy.blog.service;

import com.lyy.blog.dao.blogrepositroy;
import com.lyy.blog.notfoundeexception;
import com.lyy.blog.po.blog;
import com.lyy.blog.po.type;
import com.lyy.blog.util.MarkdownUtils;
import com.lyy.blog.util.MyBeanUtils;
import com.lyy.blog.vo.BlogQuery;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.*;
import java.util.*;

@Service
public class blogserviceimpl implements blogservice {

    @Autowired
    private blogrepositroy blogrepositroy;
    @Override
    public blog getblog(Long id) {
        return blogrepositroy.getOne(id);
    }

    @Override
    public Page<blog> listblog(Pageable pageable, BlogQuery blog) {
        return  blogrepositroy.findAll(new Specification<blog>() {
            @Override
            public Predicate toPredicate(Root<com.lyy.blog.po.blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                List<Predicate> predicates=new ArrayList<>();
                if (!"".equals(blog.getTitle()) && blog.getTitle() != null) {
                    predicates.add(cb.like(root.<String>get("title"), "%"+blog.getTitle()+"%"));
                }
                if (blog.getTypeId() != null) {
                    predicates.add(cb.equal(root.<type>get("type").get("id"), blog.getTypeId()));
                }
                if (blog.isRecommend()) {
                    predicates.add(cb.equal(root.<Boolean>get("recommend"), blog.isRecommend()));
                }
                cq.where(predicates.toArray(new Predicate[predicates.size()]));
                return null;


            }
        },pageable);


    }

    //修改和新增的保存
    @Transactional
    @Override
    public blog savablog(blog blog) {

        //根据是否有id区别新增和修改
        if(blog.getId()==null){

            blog.setCreateTime(new Date());

            blog.setUpdateTime(new Date());
            blog.setViews(0);
        }else {
            blog.setUpdateTime(new Date());
        }


        return blogrepositroy.save(blog);
    }

    @Transactional
    @Override
    public blog updateblog(Long id, blog blog) {

       blog b=blogrepositroy.getOne(id);
        if(b==null){
            throw  new notfoundeexception("不存在这个");

        }
        //////这而不太明白
        BeanUtils.copyProperties(blog,b, MyBeanUtils.getNullPropertyNames(blog));

        b.setUpdateTime(new Date());
        return blogrepositroy.save(b);


    }

    @Transactional
    @Override
    public void deleteblog(Long id) {

        blogrepositroy.deleteById(id);

    }

    @Override
    public Page<blog> listblog(Pageable pageable) {
        return blogrepositroy.findAll(pageable);
    }

    @Override
    public List<blog> listrecommendtop(Integer size) {

        Pageable pageable= PageRequest.of(0,size, Sort.Direction.DESC,"updateTime");
        return blogrepositroy.findTop(pageable);
    }

    @Override
    public Page<blog> listblog(String query, Pageable pageable) {
         return blogrepositroy.findByQuery(query,pageable);
    }

    @Override
    @Transactional
    public blog getAndConvert(Long id) {
        blog blog = blogrepositroy.getOne(id);
        if (blog == null) {
            throw new notfoundeexception("该博客不存在");
        }
        blog b = new blog();
        BeanUtils.copyProperties(blog,b);
        String content = b.getContent();
        b.setContent(MarkdownUtils.markdownToHtmlExtensions(content));
        blogrepositroy.updateViews(id);
        return b;
    }

    @Override
    public Page<blog> listblog(Long tagId, Pageable pageable) {
        return  blogrepositroy.findAll(new Specification<blog>() {
            @Override
            public Predicate toPredicate(Root<blog> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                Join join = root.join("tags");

                return cb.equal(join.get("id"),tagId);
            }
        },pageable);
    }

    @Override
    public Map<String, List<blog>> archiveBlog() {
        List<String> years = blogrepositroy.findGroupYear();
        Map<String, List<blog>> map = new LinkedHashMap<>();
        for (String year : years) {
            map.put(year, blogrepositroy.findByYear(year));
        }
        return map;
    }

    public Long countBlog() {
        return blogrepositroy.count();
    }

}
